package com.chhuang.utils.string;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.acegisecurity.providers.encoding.MessageDigestPasswordEncoder;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;

/**
 * md5工具类
 * @author 黄晨
 * @date 2016-2-1
 *
 */
public class Md5Util {
	
	private static final String MD5 = "MD5";
	private static MessageDigest md = null;
	private static MessageDigestPasswordEncoder mdpeMd5 = null;
	 
    static {
        try {
            md = MessageDigest.getInstance(MD5);
            mdpeMd5 = new MessageDigestPasswordEncoder(MD5);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
	
	/**
	 * 生成参数的md5值
	 * @param key
	 * @return
	 */
	public static String md5(String key) {
		if(StringUtil.isEmpty(key)) {
			return null;
		}
		return DigestUtils.md5Hex(key);
	}
	
	/**
	 * 生成带加密盐的密码
	 * @param key
	 * @param salt
	 * @return
	 */
	public static String md5(String key, String salt) {
		if(StringUtil.isEmpty(key)) {
			return null;
		}
		if(StringUtil.isEmpty(salt)){
			salt = "";
		}
		
		mdpeMd5.setEncodeHashAsBase64(false);
		
		return mdpeMd5.encodePassword(key, salt);
	}
	
	/**
     * 计算大文件流的md5值
     * @param inputStream
     * @return
     */
    public static String md5(InputStream inputStream) {
    	if(inputStream==null){
    		return null;
    	}
    	String md5 = null;
        try {
            byte[] buffer = new byte[8192];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                md.update(buffer, 0, length);
            }
            md5 = new String(Hex.encodeHex(md.digest()));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return md5;
    }
 
    /**
     * 计算文件的md5值 大于1m用自己的方法，小于1m用DigestUtils.md5Hex
     * @param file 要求md5值的文件
     * @return
     */
    public static String md5(File file) {
    	if(file==null){
    		return null;
    	}
    	String md5 = null;
    	FileInputStream fis = null;
        try {
        	fis = new FileInputStream(file);
        	long len = file.length();
        	if(len < 1l<<10<<10){//小于1m的文件
        		md5 = DigestUtils.md5Hex(fis);
        	}else{
        		md5 = md5(fis);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(fis!=null)fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return md5;
    }
    
}
